package c2.advanced.business.help;

import c2.advanced.business.AdvancedBody;
import c2.advanced.share.RpcSuit;
import c2.cross.business.help.adventure.CrossAdventureData;
import c2.cross.business.help.snapshot.CrossSnapshotData;
import cate.common.util.TimeTool;
import cate.game.chat.ChatContentParam;
import cate.game.cross.core.CrossSyncAdventure;
import cate.game.cross.msg.CrossHelpInnerMsg;
import cate.game.cross.msg.CrossLambReq;
import cate.game.play.part.PlaySide;
import cate.game.role.RoleSnapshot;
import cp.solution.rpc.RpcMsgHead;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@NoteClass("跨服公共帮助模块")
public class AdvancedHelpFacade {
    @NoteField("AdvancedBody")
    private final AdvancedBody context;
    @NoteField("缓存的主线阵容")
    private final Map<String, CrossAdventureData> cachedAdventureMap = new ConcurrentHashMap<>();
    @NoteField("缓存的快照")
    private final Map<String, CrossSnapshotData> cachedSnapshotMap = new ConcurrentHashMap<>();

    public AdvancedHelpFacade(AdvancedBody context) {
        this.context = context;
    }

    /**
     * RPC
     */
    private RpcSuit rpc() {
        return context.rpc;
    }

    /**
     * RPC注册
     */
    public void rpcRegister() {
        rpc().recv().onFireAndForgetTemplate(CrossHelpInnerMsg.SYNC_ADVENTURE, CrossSyncAdventure.class, this::syncAdventure);
        rpc().recv().onFireAndForgetTemplate(CrossHelpInnerMsg.SYNC_SNAPSHOT, RoleSnapshot.class, this::syncSnapshot);
    }

    /**
     * 循环
     */
    public void tick() {
        long nowTime = System.currentTimeMillis();
        // 检测缓存释放
        cachedAdventureMap.entrySet().removeIf(e -> e.getValue().timeoutTime >= nowTime);
    }

    /**
     * 同布主线阵容
     *
     * @param head 消息头
     * @param csa  主线信息
     */
    private void syncAdventure(RpcMsgHead head, CrossSyncAdventure csa) {
        if (csa == null || csa.roleUid == null || csa.playSide == null) {
            return;
        }
        CrossAdventureData data;
        if (cachedAdventureMap.containsKey(csa.roleUid)) {
            data = cachedAdventureMap.get(csa.roleUid);
        } else {
            data = new CrossAdventureData();
            data.uid = csa.roleUid;
        }
        data.playSide = csa.playSide;
        context.dbBase().cross_adventure.save(data);
    }

    /**
     * 获取主线阵容
     *
     * @param uid 唯一ID
     */
    public PlaySide getAdventure(String uid) {
        if (cachedAdventureMap.containsKey(uid)) {
            return cachedAdventureMap.get(uid).playSide;
        }
        CrossAdventureData data = context.dbBase().cross_adventure.get(uid);
        if (data == null) {
            return null;
        }
        data.timeoutTime = System.currentTimeMillis() + 5 * TimeTool.TimeCons.MINUTE;
        cachedAdventureMap.put(uid, data);
        return data.playSide;
    }

    /**
     * 同布快照
     *
     * @param head     消息头
     * @param snapshot 快照
     */
    private void syncSnapshot(RpcMsgHead head, RoleSnapshot snapshot) {
        if (snapshot == null) {
            return;
        }
        CrossSnapshotData data;
        if (cachedSnapshotMap.containsKey(snapshot.uid)) {
            data = cachedSnapshotMap.get(snapshot.uid);
        } else {
            data = new CrossSnapshotData();
            data.uid = snapshot.uid;
        }
        data.snapshot = snapshot;
        context.dbBase().cross_snapshot.save(data);
    }

    /**
     * 获取快照
     *
     * @param uid 唯一ID
     */
    public RoleSnapshot getSnapshot(String uid) {
        if (cachedSnapshotMap.containsKey(uid)) {
            return cachedSnapshotMap.get(uid).snapshot;
        }
        CrossSnapshotData data = context.dbBase().cross_snapshot.get(uid);
        if (data == null) {
            return null;
        }
        data.timeoutTime = System.currentTimeMillis() + 5 * TimeTool.TimeCons.MINUTE;
        cachedSnapshotMap.put(uid, data);
        return data.snapshot;
    }

    /**
     * 通知游戏服添加跑马灯
     *
     * @param lampId 跑马灯ID
     * @param args 参数
     */
    public void broadcastLampNotice(int lampId, ChatContentParam... args) {
        List<ChatContentParam> params = Arrays.asList(args);
        broadcastLampNotice(lampId, params);
    }

    /**
     * 通知游戏服添加跑马灯
     *
     * @param lampId 跑马灯ID
     * @param params 参数
     */
    public void broadcastLampNotice(int lampId, List<ChatContentParam> params) {
        try {
            rpc().send().fireAndForgetGameInCrossTemplate(CrossHelpInnerMsg.SHOW_LAMB, context.getCode(), new CrossLambReq(lampId, params));
        } catch (Exception e) {
            log.error("", e);
        }
    }
}
